package com.ruoyi.wx;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import cn.hutool.core.text.CharSequenceUtil;
import com.github.binarywang.wxpay.bean.order.WxPayAppOrderResult;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.order.WxPayNativeOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.request.WxPayRefundV3Request;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;

import java.math.BigDecimal;

/**
 * 微信常规支付
 *
 * @author yql
 */
public class WxPayUtils {
    private static WxModel wxModel;

    public static void setWxModel(WxModel wxModel) {
        WxPayUtils.wxModel = wxModel;
    }

    /**
     * 小程序-微信用户相关配置
     */
    public static WxMaService getMiniWxMaService() {
        WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
        config.setAppid(wxModel.getMiniAppId());
        config.setSecret(wxModel.getMiniAppSecret());
        config.setMsgDataFormat("JSON");
        WxMaService wxMaService = new WxMaServiceImpl();
        wxMaService.setWxMaConfig(config);
        return wxMaService;
    }


    /**
     * 小程序-微信支付相关配置
     */
    public static WxPayService getMiniWxPayService() {
        WxPayConfig payConfig = new WxPayConfig();
        payConfig.setAppId(wxModel.getMiniAppId());
        payConfig.setMchId(wxModel.getMchId());
        payConfig.setMchKey(wxModel.getMchKey());
        payConfig.setTradeType("JSAPI");
        payConfig.setSignType("MD5");
        payConfig.setKeyPath(wxModel.getKeyPath());
        payConfig.setApiV3Key(wxModel.getV3Key());
        payConfig.setPrivateCertPath(wxModel.getPrivateCertPath());
        payConfig.setPrivateKeyPath(wxModel.getPrivateKeyPath());
        WxPayService wxPayService = new WxPayServiceImpl();
        wxPayService.setConfig(payConfig);
        return wxPayService;
    }

    /**
     * app-微信支付相关配置
     */
    public static WxPayService getWxPayService() {
        WxPayConfig payConfig = new WxPayConfig();
        payConfig.setAppId(wxModel.getAppId());
        payConfig.setMchId(wxModel.getMchId());
        payConfig.setMchKey(wxModel.getMchKey());
        payConfig.setTradeType("APP");
        payConfig.setSignType("MD5");
        WxPayService wxPayService = new WxPayServiceImpl();
        wxPayService.setConfig(payConfig);
        return wxPayService;
    }

    public static WxPayService getWxPayH5Service() {
        WxPayConfig payConfig = new WxPayConfig();
        payConfig.setAppId(wxModel.getAppId());
        payConfig.setMchId(wxModel.getMchId());
        payConfig.setMchKey(wxModel.getMchKey());
        payConfig.setTradeType("NATIVE");
        payConfig.setSignType("MD5");
        WxPayService wxPayService = new WxPayServiceImpl();
        wxPayService.setConfig(payConfig);
        return wxPayService;
    }

    /**
     * app-微信支付下单
     * @param boby 商品描述
     * @param orderNo 订单号
     * @param payMoney 订单金额
     * @param notifyUrl 回调地址
     * @return 支付响应对象
     * @throws WxPayException 微信支付异常
     */
    public static WxPayAppOrderResult weChatPay_app(String boby, String orderNo, BigDecimal payMoney, String notifyUrl) throws WxPayException {
        WxPayService wxPayService = getWxPayService();
        //拉起支付
        WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = WxPayUnifiedOrderRequest.newBuilder()
                .body(boby)
                .outTradeNo(orderNo)
                .totalFee(payMoney.multiply(BigDecimal.valueOf(100)).intValue())
                .spbillCreateIp(wxModel.getSpbillCreateIp())
                .notifyUrl(CharSequenceUtil.format("{}{}", wxModel.getBaseUrl(), notifyUrl))
                .build();
        return wxPayService.createOrder(wxPayUnifiedOrderRequest);
    }


    /**
     * 小程序-微信支付下单
     *
     * @param boby      商品描述
     * @param orderNo   订单号
     * @param openId    用户openid
     * @param payMoney  账号余额
     * @param notifyUrl 回调地址
     * @return 经过封装的{@link WxPayMpOrderResult}
     * @throws WxPayException 支付异常
     */
    public static WxPayMpOrderResult weChatPay_mini(String boby, String orderNo, String openId, BigDecimal payMoney, String notifyUrl) throws WxPayException {
        final WxPayService wxPayService = getMiniWxPayService();
        //拉起支付
        WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = WxPayUnifiedOrderRequest.newBuilder()
                .body(boby)
                .outTradeNo(orderNo)
                .openid(openId)
                .totalFee(payMoney.multiply(BigDecimal.valueOf(100)).intValue())
                .spbillCreateIp(wxModel.getSpbillCreateIp())
                .notifyUrl(CharSequenceUtil.format("{}{}", wxModel.getBaseUrl(), notifyUrl))
                .build();
        return wxPayService.createOrder(wxPayUnifiedOrderRequest);
    }

    /**
     * H5-微信支付下单
     *
     * @param boby      商品描述
     * @param orderNo   订单号
     * @param payMoney  金额
     * @param notifyUrl 回调地址
     * @return 支付响应参数
     * @throws WxPayException 支付异常
     */
    public static WxPayNativeOrderResult weChatPay_h(String boby, String orderNo, BigDecimal payMoney, String notifyUrl) throws WxPayException {
        final WxPayService wxPayService = getWxPayH5Service();
        //拉起支付
        WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = WxPayUnifiedOrderRequest.newBuilder()
                .body(boby)
                .outTradeNo(orderNo)
                .totalFee(payMoney.multiply(BigDecimal.valueOf(100)).intValue())
                .spbillCreateIp(wxModel.getSpbillCreateIp())
                .notifyUrl(CharSequenceUtil.format("{}{}", wxModel.getBaseUrl(), notifyUrl))
                .tradeType("NATIVE")
                .productId("12235413214070356458058")
                .build();
        return wxPayService.createOrder(wxPayUnifiedOrderRequest);
    }

    /**
     * 小程序v2退款
     *
     * @param payNo    支付单号
     * @param refundNo 退款单号
     * @param total    总金额
     * @param refund   退款金额
     * @throws WxPayException 微信操作异常
     */

    public static void getMiniWxRefundV3(String payNo, String refundNo, Integer total, Integer refund) throws WxPayException {
        WxPayService service = getMiniWxPayService();
        WxPayRefundV3Request request = new WxPayRefundV3Request();
        WxPayRefundV3Request.Amount amount = new WxPayRefundV3Request.Amount();
        amount.setTotal(total);
        amount.setRefund(refund);
        amount.setCurrency("CNY");
        request.setTransactionId(payNo);
        request.setOutRefundNo(refundNo);
        request.setAmount(amount);
        service.refundV3(request);
    }

    /**
     * 小程序V2 退款
     *
     * @param payNo    支付单号
     * @param refundNo 退款单号
     * @param total    总金额
     * @param refund   退款金额
     * @throws WxPayException 微信服务异常
     */
    public static void getMiniWxRefundV2(String payNo, String refundNo, Integer total, Integer refund) throws WxPayException {
        WxPayService service = getMiniWxPayService();
        WxPayRefundRequest request = new WxPayRefundRequest();
        request.setTransactionId(payNo);
        request.setOutRefundNo(refundNo);
        request.setTotalFee(total);
        request.setRefundFee(refund);
        service.refundV2(request);
    }

}
